<?php
/********************************************************************
 *	Author:
 *		Jestery Liu <jestery@gmail.com>
 *		http://www.pte.cn
 *
 *	File:			Loader.class.php
 *	Create Date:	2007-05-12 11:37:52 CST
 *******************************************************************/

class Loader
{
	const CLASS_TYPE_USER_DEFINED = 'USER_DEFINED';
	const CLASS_TYPE_CORE_LIB = 'CORE_LIB';

	private function __construct() {}

	public static function autoload($className)
	{
		if (class_exists($className, false))
		{
			return;
		}
		if (false === $classFile = self::userClassExists($className))
		{
			$classFile = self::coreLibClassExists($className);
		}
		if ($classFile===false)
		{
			throw new Exception("Class $className can't be found.");
		}
		require_once($classFile);
	}

	public static function loadClass($className, $type=self::CLASS_TYPE_USER_DEFINED)
	{
		if(class_exists($className, false))
		{
			return;
		}
		if ($type==self::CLASS_TYPE_USER_DEFINED)
		{
			self::loadUserClass($className);
		}
		elseif ($type==self::CLASS_TYPE_CORE_LIB)
		{
			self::loadCoreLibClass($className);
		}
		else
		{
			throw new Exception("Undefined type.");
		}
	}

	public static function loadUserClass($className)
	{
		if (class_exists($className, false))
		{
			return;
		}
		if ($classFile = self::userClassExists($className))
		{
			require_once($classFile);
			return;
		}
		else
		{
			throw new Exception("Class $className does not exists in user defined classes' path.");
		}
	}

	public static function loadCoreLibClass($className)
	{
		if (class_exists($className, false))
		{
			return;
		}
		if ($classFile = self::coreLibClassExists($className))
		{
			require_once($classFile);
		}
		else
		{
			throw new Exception("Class $className does not exists in core lib's path.");
		}
	}

	public static function classExists($className, $dirs=null)
	{
		if (preg_match('/[^a-z0-9\-_.]/i', $className))
		{
			throw new Exception('Security check: Illegal character in class name');
		}
		if (is_null($dirs))
		{
			$dirs = PTE::getCoreLibsPath();
		}
		$dirs = (array)$dirs;
		foreach ($dirs as $dir)
		{
			$dir = PTE::normalizePath($dir);
			$filename = $dir.$className.'.class.php';
			$interfaceFilename = $dir.$className.'.interface.php';
			$fn = self::fileExists($filename);
			return $fn ? $fn : self::fileExists($interfaceFilename);
		}
	}

	public static function userClassExists($className)
	{
		return self::classExists($className, PTE::getUserDefinedClassesPath());
	}

	public static function coreLibClassExists($className)
	{
		return self::classExists($className, PTE::getCoreLibsPath());
	}

	public static function fileExists($filename)
	{
		return is_readable($filename) ? $filename : false;
	}

	public static function loadPEAR($pkg)
	{
		require_once (PTE::getPearPath().$pkg.'.php');
	}
	
	public static function loadModule($name)
	{
		$appmod = explode('.', $name);
		if (count($appmod)!=2)
		{
			throw new Exception('Invalid format $name. The valid format is appName.moduleName');
		}
		$modfile = PTE::getApplicationPath($appmod[0]).PTE::getModuleFileName($appmod[1]);
		if (self::fileExists($modfile))
		{
			include_once($modfile);
		}
		else
		{
			throw new Exception("Module file ($modfile) does not exists.");
		}
	}
	public static function loadModel($name)
	{
		$modfile = PTE::getModelsPath().PTE::getModelFileName($name);
		if (self::fileExists($modfile))
		{
			include_once($modfile);
		}
		else
		{
			throw new Exception("Model file ($modfile) does not exists.");
		}
	}
}

/* vim: set ts=4 sw=4 ff=unix: */
